home *** CD-ROM | disk | FTP | other *** search
/ Apple WWDC 1996 / WWDC96_1996 (CD).toast / Technology Materials / QuickTime VR / MacOS / QuickDraw™ 3D 1.0.6F4 SDK / Samples / SampleCode / CustomAttribute / CustomAttributesShell.c < prev    next >
Encoding:
C/C++ Source or Header  |  1996-02-20  |  14.3 KB  |  565 lines  |  [TEXT/MPCC]

  1. // Quickdraw 3D sample code
  2. //
  3. // Nick Thompson, AppleLink: DEVSUPPORT (devsupport@applelink.apple.com)
  4. //
  5. // ©1994-5 Apple Computer Inc., All Rights Reserved
  6.  
  7. // system headers
  8. #include <Desk.h>
  9. #include <Dialogs.h>
  10. #include <DiskInit.h>
  11. #include <Fonts.h>
  12. #include <Menus.h>
  13. #include <PictUtil.h>
  14. #include <QDOffScreen.h>
  15. #include <QuickDraw.h>
  16. #include <SegLoad.h>
  17. #include <StandardFile.h>
  18. #include <TextEdit.h>
  19. #include <ToolUtils.h>
  20. #include <TextUtils.h>
  21. #include <Strings.h>
  22.  
  23. // for QuickDraw 3D
  24. #include <QD3D.h>
  25. #include <QD3DMath.h>
  26. #include <QD3DDrawContext.h>
  27. #include <QD3DShader.h>
  28. #include <QD3DTransform.h>
  29. #include <QD3DGroup.h>
  30. #include <QD3DCamera.h>
  31. #include <QD3DPick.h>
  32. #include <QD3DString.h>
  33.  
  34. #include "CustomAttributesShell.h"
  35. #include "CustomAttributesSupport.h"
  36. #include "MyErrorHandler.h"
  37.  
  38. #include "CustomAttribute_Lib.h"
  39.  
  40. //-------------------------------------------------------------------------------------------
  41. // function prototypes
  42.  
  43. static void         InitToolbox( void ) ;
  44. static void         MainEventLoop( void ) ;
  45. static void            HandleMenuChoice(DocumentPtr theDocument, long menuChoice);
  46. static void         HandleKeyPress(EventRecord *event) ;
  47. static void         HandleOSEvent(EventRecord *event) ;
  48. void InitDocumentData( DocumentPtr theDocument ) ;
  49. TQ3Status DocumentDraw3DData( DocumentPtr theDocument ) ;
  50. void DisposeDocumentData( DocumentPtr theDocument) ;
  51.  
  52. //-------------------------------------------------------------------------------------------
  53. //
  54.  
  55. Boolean         gQuitFlag         = false ;
  56. WindowPtr        gMainWindow        = nil ;
  57. DocumentRec        gDocument ;
  58.  
  59. //-------------------------------------------------------------------------------------------
  60. // main()
  61. // entry point for the application, initialize the toolbox, initialize QuickDraw 3D
  62. // and enter the main event loop.  On exit from the main event loop, we want to call
  63. // the QuickDraw 3D exit function to clean up QuickDraw 3d.
  64.  
  65. void main(void)
  66. {
  67.     TQ3Status    myStatus;
  68.     Rect        rBounds = { 50, 50, 350, 350 } ;
  69.     Str255        title = "\pSpinning Box" ;
  70.     FSSpec        theFileSpec ;                // the file we are opening
  71.  
  72.     InitToolbox() ;
  73.  
  74.     if(MetafileFileSpecify( &theFileSpec )) {
  75.     
  76.         SetCursor(*(GetCursor(watchCursor)));
  77.         
  78.         //    Initialize QuickDraw 3D, open a connection to the QuickDraw 3D library
  79.         myStatus = Q3Initialize();
  80.         if ( myStatus == kQ3Failure ) {
  81.             DebugStr("\pErInitialize returned failure.");    
  82.             ExitToShell() ;
  83.         }
  84.                         
  85.         // install the error handler - this gets called whenever
  86.         // an error occurs, which means we don't have to check so 
  87.         // much
  88.         Q3Error_Register( MyErrorHandler, 0L );        
  89.         Q3Warning_Register( MyWarningHandler, 0L );        
  90.  
  91.         /* Go ahead and register all custom attributes */
  92.         RegisterAllCustomAttributes();
  93.         
  94.         // set up our globals
  95.         gQuitFlag = false ;
  96.         gMainWindow = NewCWindow(nil,&rBounds,title,false,noGrowDocProc,(WindowPtr)-1,true,0); ;
  97.  
  98.         // initialise our document structure
  99.         InitDocumentData( &gDocument ) ;
  100.         
  101.         // try to read the file into the main display group
  102.         if( MyNewModelFromFile(&theFileSpec, &gDocument) != NULL ) {        
  103.  
  104.             AdjustCamera(    &gDocument,
  105.                             (gMainWindow->portRect.right - gMainWindow->portRect.left),
  106.                             (gMainWindow->portRect.bottom - gMainWindow->portRect.top) ) ;
  107.  
  108.             SetWTitle( gMainWindow, theFileSpec.name );
  109.             ShowWindow( gMainWindow ) ;
  110.             SetPort( gMainWindow ) ;
  111.     
  112.             SetCursor(&qd.arrow) ;
  113.             MainEventLoop();
  114.             
  115.         }
  116.                 
  117.         DisposeDocumentData( &gDocument ) ;
  118.         
  119.         UnregisterAllCustomAttributes();
  120.         
  121.         //    Close our connection to the QuickDraw 3D library
  122.         myStatus = Q3Exit();
  123.         if ( myStatus == kQ3Failure )
  124.             DebugStr("\pErExit returned failure.");
  125.     }    
  126. }
  127.  
  128. //-------------------------------------------------------------------------------------------
  129. //
  130.  
  131. void InitDocumentData( DocumentPtr theDocument ) 
  132. {
  133.     TQ3Point3D        myOrigin = { 0, 0, 0 } ;
  134.     TQ3WindowPointPickData    data;
  135.                 
  136.     
  137.     // sets up the 3d data for the scene
  138.     //    Create view for QuickDraw 3D.
  139.     theDocument->fView = MyNewView( gMainWindow );
  140.  
  141.     // the main display group:
  142.     theDocument->fModel = NULL ;
  143.     
  144.     
  145.     // the drawing styles:
  146.     theDocument->fInterpolation = Q3InterpolationStyle_New(kQ3InterpolationStyleNone) ;
  147.     theDocument->fBackFacing = Q3BackfacingStyle_New(kQ3BackfacingStyleRemove ) ;
  148.     theDocument->fFillStyle = Q3FillStyle_New(kQ3FillStyleFilled ) ;
  149.  
  150.  
  151.     theDocument->fGroupScale = 1;                
  152.     theDocument->fGroupCenter = myOrigin ;            
  153.  
  154.     // set the rotation matrix the identity matrix
  155.     Q3Matrix4x4_SetIdentity(&theDocument->fRotation);    
  156.     
  157.     theDocument->fStringObject = NULL;            
  158.     theDocument->fName = NULL;            
  159.     theDocument->fDescription = NULL;    
  160.  
  161.     data.data.sort                 = kQ3PickSortNone;
  162.     data.data.numHitsToReturn    = 1;
  163.     data.data.mask                 = kQ3PickDetailMaskObject;
  164.  
  165.     data.point.x = 0;
  166.     data.point.y = 0;
  167.  
  168.     data.vertexTolerance    = 
  169.     data.edgeTolerance        = 3;
  170.     
  171.     theDocument->launchNetscape = kQ3False;
  172.  
  173.     theDocument->units = 1.0;
  174.  
  175.     theDocument->fPickObject = Q3WindowPointPick_New(&data);
  176.     
  177.     return ;
  178.     
  179. bail:
  180.     // either we failed getting the model or the view
  181.     // so we want to quit here
  182.     ExitToShell() ;
  183.     
  184. }
  185.  
  186. void DisposeDocumentData( DocumentPtr theDocument)
  187. {
  188.     Q3Object_Dispose(theDocument->fView) ;                // the view for the scene
  189.     Q3Object_Dispose(theDocument->fModel) ;                // object in the scene being modelled
  190.     Q3Object_Dispose(theDocument->fInterpolation) ;        // interpolation style used when rendering
  191.     Q3Object_Dispose(theDocument->fBackFacing) ;        // whether to draw shapes that face away from the camera
  192.     Q3Object_Dispose(theDocument->fFillStyle) ;            // whether drawn as solid filled object or decomposed to components
  193.     if(theDocument->fStringObject) {
  194.         Q3CString_EmptyData(&theDocument->fName);
  195.         Q3Object_Dispose(theDocument->fStringObject) ;
  196.     }
  197.     if( theDocument->fDescription ) {
  198.         Q3CString_EmptyData(&theDocument->fDescString);
  199.         Q3Object_Dispose(theDocument->fDescription);
  200.     }
  201.     if(theDocument->fPickObject)
  202.         Q3Object_Dispose(theDocument->fPickObject) ;
  203. }
  204. //-----------------------------------------------------------------------------
  205. // assumes the port is set up before being called
  206.  
  207. TQ3Status DocumentDraw3DData( DocumentPtr theDocument )
  208. {
  209.     TQ3Status theStatus ;    
  210.     
  211.     Q3View_StartRendering(theDocument->fView) ;
  212.     do {
  213.         theStatus = SubmitScene( theDocument ) ;
  214.     } while (Q3View_EndRendering(theDocument->fView) == kQ3ViewStatusRetraverse );
  215.  
  216.     return theStatus ;    
  217.  
  218.     
  219. }
  220.  
  221.  
  222. //----------------------------------------------------------------------------------
  223.  
  224. //-------------------------------------------------------------------------------------------
  225. //
  226.  
  227. short HiWrd(long aLong)
  228. {
  229.     return    (((aLong) >> 16) & 0xFFFF) ;
  230. }
  231.  
  232. //-------------------------------------------------------------------------------------------
  233. //
  234.  
  235. short LoWrd(long aLong)
  236. {
  237.     return    ((aLong) & 0xFFFF) ;
  238.  
  239. }
  240.  
  241. //-------------------------------------------------------------------------------------------
  242. //
  243.  
  244. void InitToolbox()
  245. {
  246.     Handle        menuBar = nil;
  247.  
  248.     MaxApplZone() ;
  249.     MoreMasters() ; MoreMasters() ; MoreMasters() ; 
  250.     
  251.     InitGraf( &qd.thePort );
  252.     InitFonts();
  253.     InitWindows();
  254.     InitCursor();
  255.     InitMenus();
  256.  
  257.     menuBar = GetNewMBar(Menu_Bar);
  258.     SetMenuBar(menuBar);
  259.  
  260.     //AddResMenu(GetMenuHandle(Apple_Menu), 'DRVR');
  261.  
  262.     DrawMenuBar();
  263.  
  264.     FlushEvents( everyEvent, 0 ) ;
  265.     // initialize application globals
  266.     
  267.     gQuitFlag = false;
  268.     
  269. }
  270.  
  271.  
  272. //-------------------------------------------------------------------------------------------
  273. //
  274. void MainEventLoop()
  275. {
  276.     EventRecord     event;
  277.     WindowPtr       window;
  278.     short           thePart;
  279.     Rect            screenRect, updateRect;
  280.     Point            aPoint = {100, 100};
  281.  
  282.     while( !gQuitFlag )
  283.     {
  284.         if (WaitNextEvent( everyEvent, &event, 0, nil ))
  285.         {
  286.  
  287.             switch (event.what) {
  288.                 case mouseDown:
  289.                 
  290.                     thePart = FindWindow( event.where, &window );
  291.                     
  292.                     switch( thePart ) {
  293.                         case inMenuBar:
  294.                             HandleMenuChoice(&gDocument,MenuSelect(event.where));
  295.                             break;
  296.                         
  297.                         case inDrag:
  298.                     
  299.                             screenRect = (**GetGrayRgn()).rgnBBox;
  300.                             DragWindow( window, event.where, &screenRect );
  301.                             break ;
  302.                     
  303.                         case inContent:
  304.                     
  305.                             if (window != FrontWindow())
  306.                                 SelectWindow( window );
  307.                             break ;
  308.                     
  309.                         case inGoAway:
  310.                             if (TrackGoAway( window, event.where )) {
  311.                                 DisposeWindow ( window );
  312.                                 gQuitFlag = true;
  313.  
  314.                             }
  315.                             break ;
  316.                             
  317.                         default:
  318.                             break ;
  319.                     }
  320.                     break ;
  321.                             
  322.                         
  323.                 case updateEvt:
  324.                 
  325.                     window = (WindowPtr)event.message;
  326.                     updateRect = (**(window->visRgn)).rgnBBox;
  327.                     SetPort( window ) ;
  328.                     BeginUpdate( window );
  329.                     DocumentDraw3DData( &gDocument ) ;
  330.                     EndUpdate( window );
  331.  
  332.                     break ;
  333.                     
  334.                 case keyDown:
  335.                 case autoKey:
  336.                     if (event.modifiers & cmdKey) {
  337.                         HandleMenuChoice(&gDocument,
  338.                             MenuKey(event.message & charCodeMask));
  339.                     } else
  340.                         HandleKeyPress(&event);
  341.                     break;
  342.                     
  343.                 case diskEvt:
  344.                     if ( HiWrd(event.message) != noErr ) 
  345.                         (void) DIBadMount(aPoint, event.message);
  346.                     break;
  347.                     
  348.                 case osEvt:
  349.                 case activateEvt:
  350.                     break;
  351.  
  352.  
  353.             }
  354.         }
  355.         else {
  356.             // we received a null event, do some hit testing
  357.             Point    mouseLocation;
  358.  
  359.             GetMouse(&mouseLocation);
  360.             if( PtInRect(mouseLocation, &((GrafPtr) window)->portRect) == true) {
  361.                 TQ3Point2D                pickPoint;
  362.                 TQ3WindowPointPickData    data;
  363.                 TQ3Status                status;
  364.                 unsigned long            numberHits;
  365.                 
  366.                 data.data.sort                 = kQ3PickSortNone;
  367.                 data.data.numHitsToReturn    = 1;
  368.                 data.data.mask                 =
  369.                       kQ3PickDetailMaskObject;
  370.             
  371.                 
  372.                 data.point.x = mouseLocation.h;
  373.                 data.point.y = mouseLocation.v;
  374.     
  375.                 data.vertexTolerance    = 
  376.                 data.edgeTolerance        = 3;
  377.                 
  378.                 pickPoint.x = mouseLocation.h;
  379.                 pickPoint.y = mouseLocation.v;
  380.                 
  381.                 Q3WindowPointPick_SetPoint(gDocument.fPickObject, &pickPoint);
  382.                             
  383.                 Q3View_StartPicking(gDocument.fView, gDocument.fPickObject);
  384.                 
  385.                 do {
  386.                     status = SubmitScene( &gDocument ) ;
  387.                 } while((Q3View_EndPicking( gDocument.fView)) == kQ3ViewStatusRetraverse );
  388.                 
  389.                 Q3Pick_GetNumHits(gDocument.fPickObject, &numberHits);
  390.                 
  391.                 if( numberHits != 0) {
  392.                     DisplayCustomAttributes(&gDocument);
  393.                 } else {
  394.                     /* Delete previously displayed text */
  395.                     if( gDocument.fStringObject ) {
  396.                         Str255            pascalString;
  397.  
  398.                         strcpy((char *) pascalString, gDocument.fName);
  399.                         MoveTo(10,10);
  400.                         DrawString(c2pstr((char *)pascalString));
  401.                         
  402.                         Q3CString_EmptyData(&gDocument.fName);
  403.                         gDocument.fName = NULL;
  404.                         Q3Object_Dispose(gDocument.fStringObject);
  405.                         gDocument.fStringObject = NULL;
  406.                     }
  407.                     if( gDocument.fDescription ) {
  408.                         Str255            pascalString;
  409.  
  410.                         /* Delete previously displayed url */
  411.                         MoveTo(10,30);
  412.                         DrawString(gDocument.fURL);
  413.         
  414.                         MoveTo(10,50);
  415.                         strcpy((char *) pascalString, gDocument.fDescString);
  416.                         DrawString(c2pstr((char *)pascalString));
  417.                         
  418.                         Q3CString_EmptyData(&gDocument.fDescString);
  419.                         
  420.                         Q3Object_Dispose(gDocument.fDescription);
  421.                         gDocument.fDescription = NULL;
  422.                     }
  423.                 }
  424.             }
  425.         }
  426.     }
  427. }
  428.  
  429.  
  430. //-------------------------------------------------------------------------------------------
  431. //
  432. void HandleKeyPress(EventRecord *event)
  433. {
  434. #pragma unused ( event )
  435. }
  436.  
  437. //-------------------------------------------------------------------------------------------
  438. //
  439.  
  440. static void HandleMenuChoice(DocumentPtr theDocument, long menuChoice)
  441. {
  442. short    theMenu;
  443. short    theItem;
  444.         
  445.     if    (menuChoice != 0)
  446.     {
  447.         MenuHandle    hMenu;
  448.         
  449.         theMenu    =    HiWord(menuChoice);
  450.         theItem    =    LoWord(menuChoice);
  451.         
  452.         if( theMenu == Apple_Menu ) {
  453.             Str255    accName;
  454.  
  455.             hMenu = GetMenu(Settings_Menu);    
  456.             GetItem(hMenu,theItem,accName);
  457.             OpenDeskAcc(accName);
  458.         } else if( theMenu == File_Menu) {
  459.             switch    (theItem)
  460.             {
  461.                 case    QuitItem:
  462.                     gQuitFlag = true;
  463.                     break;
  464.                     
  465.                 case    OpenItem:
  466.                     {
  467.                         FSSpec        theFileSpec ;                // the file we are opening
  468.     
  469.                         if(MetafileFileSpecify( &theFileSpec )) {
  470.                             DisposeDocumentData( &gDocument ) ;
  471.                             
  472.                             InitDocumentData( &gDocument ) ;
  473.                             
  474.                             // try to read the file into the main display group
  475.                             if( MyNewModelFromFile(&theFileSpec, &gDocument) != NULL ) {        
  476.                     
  477.                                 AdjustCamera(    &gDocument,
  478.                                                 (gMainWindow->portRect.right - gMainWindow->portRect.left),
  479.                                                 (gMainWindow->portRect.bottom - gMainWindow->portRect.top) ) ;
  480.                     
  481.                                 SetWTitle( gMainWindow, theFileSpec.name );
  482.                                 SetPort( gMainWindow ) ;
  483.  
  484.                                 DocumentDraw3DData(&gDocument);
  485.                         
  486.                                 SetCursor(&qd.arrow) ;
  487.                             }
  488.                         }
  489.                     }
  490.                     break;
  491.                 default:
  492.                     break;
  493.             }
  494.         } else if(theMenu == Settings_Menu) {
  495.             TQ3TransformObject    scaleTransform = NULL;
  496.             TQ3GroupPosition    position;
  497.             TQ3Vector3D            newScale;
  498.             
  499.             if( theItem != Netscape) {
  500.                 Q3Group_GetFirstPositionOfType(theDocument->fModel, kQ3ShapeTypeTransform, &position);
  501.                 
  502.                 Q3Group_GetPositionObject(theDocument->fModel, position, &scaleTransform);
  503.                 Q3ScaleTransform_Get(scaleTransform, &newScale);
  504.             }
  505.             
  506.             hMenu = GetMenu(Settings_Menu);    
  507.             switch    (theItem)
  508.             {
  509.                 case    Scale1M:
  510.                     CheckItem(hMenu, Scale1M, true);
  511.                     CheckItem(hMenu, Scale10M, false);
  512.                     CheckItem(hMenu, Scale100M, false);
  513.                     CheckItem(hMenu, Scale1KM, false);
  514.                     newScale.x  = newScale.y = newScale.z = theDocument->units;
  515.                     Q3ScaleTransform_Set(scaleTransform, &newScale);
  516.                     break;
  517.                     
  518.                 case    Scale10M:
  519.                     CheckItem(hMenu, Scale1M, false);
  520.                     CheckItem(hMenu, Scale10M, true);
  521.                     CheckItem(hMenu, Scale100M, false);
  522.                     CheckItem(hMenu, Scale1KM, false);
  523.                     newScale.x  = newScale.y = newScale.z = theDocument->units / 10.0;
  524.                     Q3ScaleTransform_Set(scaleTransform, &newScale);
  525.                     break;
  526.                     
  527.                 case    Scale100M:
  528.                     CheckItem(hMenu, Scale1M, false);
  529.                     CheckItem(hMenu, Scale10M, false);
  530.                     CheckItem(hMenu, Scale100M, true);
  531.                     CheckItem(hMenu, Scale1KM, false);
  532.                     newScale.x  = newScale.y = newScale.z = theDocument->units / 100.0;
  533.                     Q3ScaleTransform_Set(scaleTransform, &newScale);
  534.                     break;
  535.                     
  536.                 case    Scale1KM:
  537.                     CheckItem(hMenu, Scale1M, false);
  538.                     CheckItem(hMenu, Scale10M, false);
  539.                     CheckItem(hMenu, Scale100M, false);
  540.                     CheckItem(hMenu, Scale1KM, true);
  541.                     newScale.x  = newScale.y = newScale.z = theDocument->units / 1000.0;
  542.                     Q3ScaleTransform_Set(scaleTransform, &newScale);
  543.                     break;
  544.                     
  545.                 case    Netscape:
  546.                     hMenu = GetMenu(Settings_Menu);
  547.                     if( theDocument->launchNetscape == kQ3True ) {
  548.                         theDocument->launchNetscape = kQ3False;
  549.                         CheckItem(hMenu, Netscape, false);
  550.                     } else {
  551.                         theDocument->launchNetscape = kQ3True;
  552.                         CheckItem(hMenu, Netscape, true);
  553.                     }
  554.                         break;
  555.             }
  556.             
  557.             if(scaleTransform) {
  558.                 DocumentDraw3DData(theDocument);
  559.                 Q3Object_Dispose(scaleTransform);
  560.             }
  561.         }
  562.         HiliteMenu(0);
  563.     }
  564. }
  565.